package com.cqcis.uip.base.framework.service.impl;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;

import com.cqcis.uip.base.framework.common.FtpFile;
import com.cqcis.uip.base.framework.service.FtpSession;
import com.cqcis.uip.base.framework.service.StreamLogOutputService;

/**
 * FTP客户端session实现
 * 
 * @author huangmy
 * @date   2008-8-16
 */
public class FtpClientSessionImpl implements FtpSession {
    private FTPClient ftp; // 客户端
    private String encoding; // 编码
    private StreamLogOutputService streamLogOutputService; // stream log 
        
    public FtpClientSessionImpl(FTPClient ftp, String encoding, StreamLogOutputService streamLogOutputService) {
    	this.ftp = ftp;
    	this.encoding = encoding;
    	this.streamLogOutputService = streamLogOutputService;
    }
    
    public FTPClient createFTPClient() {
    	return null;
    }
    
    public StreamLogOutputService getStreamLogOutputService() {    	
    	return this.streamLogOutputService;
    }
	
    public void close() throws Exception {
    	this.ftp.logout();
    	this.ftp.disconnect();
    }
    
    public boolean cwd(String newWorkingDir) throws Exception {
    	return this.ftp.changeWorkingDirectory(newWorkingDir);    	
    }
    
    public InputStream retrieveFileStream(String remoteName) throws IOException {
    	return this.ftp.retrieveFileStream(remoteName);
    }
    
    public boolean retrieveFileStream(String remoteName, OutputStream local) throws IOException {
    	return this.ftp.retrieveFile(remoteName, local);
    }
    
	public boolean appendFile(String remoteFileName, InputStream local)
			throws Exception {		
		return this.ftp.appendFile(remoteFileName, local);
	}

	public boolean delete(String pathname) throws Exception {		
		return this.ftp.deleteFile(pathname);
	}

	public OutputStream getAppendStream(String remoteFileName) throws Exception {		
		return this.ftp.appendFileStream(remoteFileName);
	}

	public OutputStream getStoreStream(String remoteFileName) throws Exception {		
		return this.ftp.storeFileStream(remoteFileName);
	}

	public String getWorkDir() throws Exception {
		return this.ftp.printWorkingDirectory();
	}
	
	public boolean completePendingCommand() throws IOException {
		return this.ftp.completePendingCommand();
	}

	public FtpFile[] listFiles(String pathname) throws Exception {		
		return translateToLocalFiles(this.ftp.listFiles(pathname));
	}

	public FtpFile[] listFiles() throws Exception {
		return translateToLocalFiles(this.ftp.listFiles());
	}
	
	/**
	 * 转换为本地编码的文件
	 * 
	 * @param files
	 * @return
	 * @throws Exception
	 */
	private FtpFile[] translateToLocalFiles(FTPFile[] files) throws Exception {
		if (files != null) {
			FtpFile[] ftpFiles = new FtpFile[files.length];
			for (int i = 0; i < files.length; i ++) {
				ftpFiles[i] = new FtpFile(files[i], toLocal(files[i].getName()));
			}
			
			return ftpFiles;
		}
		
		return null;
	}

	public String[] listNames(String pathname) throws Exception {		
		return translateToLocalStrings(this.ftp.listNames(pathname));
	}
	
	/**
	 * 转换为本地编码字符串
	 * 
	 * @param names
	 * @return
	 * @throws Exception
	 */
	private String[] translateToLocalStrings(String[] names) throws Exception {
		if (names != null) {
			String[] fileNames = new String[names.length];
			for (int i = 0; i < names.length; i ++) {
				fileNames[i] = toLocal(names[i]); 
			}
			return fileNames;
		}
		
		return null;
	}
	
	/**
	 * 转换为本地编码
	 * 
	 * @param name
	 * @return
	 * @throws Exception
	 */
	private String toLocal(String name) throws Exception {
		return new String(name.getBytes("ISO-8859-1"), this.encoding);
	}

	public String[] listNames() throws Exception {		
		return translateToLocalStrings(this.ftp.listNames());
		
	}

	public boolean mkdir(String pathname) throws Exception {		
		return this.ftp.makeDirectory(pathname);
	}

	public boolean removeDir(String pathname) throws Exception {		
		return this.ftp.removeDirectory(pathname);
	}

	public boolean rename(String from, String to) throws Exception {		
		return this.ftp.rename(from, to);
	}

	public boolean storeFile(String remoteFileName, InputStream local)
			throws Exception {		
		return this.ftp.storeFile(remoteFileName, local);
	}
}
